using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using AutoMapper;
using AiPlatformAdmin.Api.Data;
using AiPlatformAdmin.Api.Models;
using AiPlatformAdmin.Api.Services;
using AiPlatformAdmin.Api.DTOs;

namespace AiPlatformAdmin.Api.Controllers
{
    [Authorize(Roles = "SystemAdministrator")]
    [ApiController]
    [Route("api/[controller]")]
    public class LlmModelsController : ControllerBase
    {
        private readonly AppDbContext _context;
        private readonly ITenantService _tenantService;
        private readonly IMapper _mapper;
        private readonly ILogger<LlmModelsController> _logger;

        public LlmModelsController(AppDbContext context, ITenantService tenantService, IMapper mapper, ILogger<LlmModelsController> logger)
        {
            _context = context;
            _tenantService = tenantService;
            _mapper = mapper;
            _logger = logger;
        }

        private int GetCurrentUserId()
        {
            var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            return int.Parse(userIdClaim ?? "0");
        }

        private async Task<int?> ResolveTenantIdAsync()
        {
            if (_tenantService.CurrentTenantId.HasValue)
            {
                return _tenantService.CurrentTenantId;
            }

            var tenantIdClaim = User.FindFirst("TenantId")?.Value;
            if (!string.IsNullOrEmpty(tenantIdClaim) && int.TryParse(tenantIdClaim, out var fromClaim))
            {
                _tenantService.SetCurrentTenantId(fromClaim);
                return fromClaim;
            }

            var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            if (!string.IsNullOrEmpty(userIdClaim) && int.TryParse(userIdClaim, out var userId))
            {
                var resolvedTenantId = await _context.Users
                    .AsNoTracking()
                    .Where(u => u.Id == userId)
                    .Select(u => (int?)u.TenantId)
                    .FirstOrDefaultAsync();

                if (resolvedTenantId.HasValue)
                {
                    _tenantService.SetCurrentTenantId(resolvedTenantId);
                    return resolvedTenantId.Value;
                }
            }

            return null;
        }

        /// <summary>
        /// 获取所有LLM模型
        /// </summary>
        [HttpGet]
        public async Task<ActionResult<IEnumerable<LlmModelDto>>> GetLlmModels()
        {
            try
            {
                var tenantId = await ResolveTenantIdAsync();
                if (!tenantId.HasValue)
                {
                    return Forbid();
                }

                var models = await _context.LlmModels
                    .Include(m => m.CreatedBy)
                    .OrderByDescending(m => m.CreatedAt)
                    .ToListAsync();

                return Ok(_mapper.Map<IEnumerable<LlmModelDto>>(models));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error fetching LLM models");
                return StatusCode(500, new { message = "获取LLM模型列表失败" });
            }
        }

        /// <summary>
        /// 根据ID获取LLM模型
        /// </summary>
        [HttpGet("{id}")]
        public async Task<ActionResult<LlmModelDto>> GetLlmModel(int id)
        {
            try
            {
                var tenantId = await ResolveTenantIdAsync();
                if (!tenantId.HasValue)
                {
                    return Forbid();
                }

                var model = await _context.LlmModels
                    .Include(m => m.CreatedBy)
                    .FirstOrDefaultAsync(m => m.Id == id);

                if (model == null)
                {
                    return NotFound(new { message = "LLM模型不存在" });
                }

                return Ok(_mapper.Map<LlmModelDto>(model));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error fetching LLM model {Id}", id);
                return StatusCode(500, new { message = "获取LLM模型失败" });
            }
        }

        /// <summary>
        /// 创建LLM模型
        /// </summary>
        [HttpPost]
        public async Task<ActionResult<LlmModelDto>> CreateLlmModel(CreateLlmModelDto dto)
        {
            try
            {
                var userId = GetCurrentUserId();
                var tenantId = await ResolveTenantIdAsync();

                if (!tenantId.HasValue)
                {
                    return Forbid();
                }

                // 检查模型名称是否已存在
                var existingModel = await _context.LlmModels
                    .AnyAsync(m => m.ModelId == dto.ModelId);

                if (existingModel)
                {
                    return BadRequest(new { message = "该模型ID已存在" });
                }

                // 解析模型类别
                if (!Enum.TryParse<LlmModelCategory>(dto.Category, out var category))
                {
                    return BadRequest(new { message = "无效的模型类别" });
                }

                var model = _mapper.Map<LlmModel>(dto);
                model.Category = category;
                model.CreatedById = userId;

                _context.LlmModels.Add(model);
                await _context.SaveChangesAsync();

                await _context.Entry(model).Reference(m => m.CreatedBy).LoadAsync();

                return CreatedAtAction(nameof(GetLlmModel), new { id = model.Id }, _mapper.Map<LlmModelDto>(model));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error creating LLM model");
                return StatusCode(500, new { message = "创建LLM模型失败" });
            }
        }

        /// <summary>
        /// 更新LLM模型
        /// </summary>
        [HttpPut("{id}")]
        public async Task<IActionResult> UpdateLlmModel(int id, UpdateLlmModelDto dto)
        {
            try
            {
                var tenantId = await ResolveTenantIdAsync();
                if (!tenantId.HasValue)
                {
                    return Forbid();
                }

                var model = await _context.LlmModels
                    .Include(m => m.CreatedBy)
                    .FirstOrDefaultAsync(m => m.Id == id);

                if (model == null)
                {
                    return NotFound(new { message = "LLM模型不存在" });
                }

                // 检查名称是否与其他模型冲突
                if (dto.ModelId != null && !string.Equals(dto.ModelId, model.ModelId, StringComparison.Ordinal))
                {
                    var existingModel = await _context.LlmModels
                        .AnyAsync(m => m.ModelId == dto.ModelId && m.Id != id);

                    if (existingModel)
                    {
                        return BadRequest(new { message = "该模型ID已存在" });
                    }

                    model.ModelId = dto.ModelId;
                }

                if (dto.Name != null)
                {
                    model.Name = dto.Name;
                }

                if (dto.Provider != null)
                {
                    model.Provider = dto.Provider;
                }

                if (dto.Category != null)
                {
                    if (!Enum.TryParse<LlmModelCategory>(dto.Category, out var category))
                    {
                        return BadRequest(new { message = "无效的模型类别" });
                    }
                    model.Category = category;
                }

                if (dto.Endpoint != null)
                {
                    model.Endpoint = dto.Endpoint;
                }

                if (dto.AccessKey != null)
                {
                    model.AccessKey = dto.AccessKey;
                }

                if (dto.Description != null)
                {
                    model.Description = dto.Description;
                }

                if (dto.IsEnabled.HasValue)
                {
                    model.IsEnabled = dto.IsEnabled.Value;
                }

                model.UpdatedAt = DateTime.UtcNow;

                await _context.SaveChangesAsync();

                return NoContent();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating LLM model {Id}", id);
                return StatusCode(500, new { message = "更新LLM模型失败" });
            }
        }

        /// <summary>
        /// 删除LLM模型
        /// </summary>
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteLlmModel(int id)
        {
            try
            {
                var tenantId = await ResolveTenantIdAsync();
                if (!tenantId.HasValue)
                {
                    return Forbid();
                }

                var model = await _context.LlmModels
                    .FirstOrDefaultAsync(m => m.Id == id);

                if (model == null)
                {
                    return NotFound(new { message = "LLM模型不存在" });
                }

                _context.LlmModels.Remove(model);
                await _context.SaveChangesAsync();

                return NoContent();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error deleting LLM model {Id}", id);
                return StatusCode(500, new { message = "删除LLM模型失败" });
            }
        }

        /// <summary>
        /// 切换LLM模型启用状态
        /// </summary>
        [HttpPatch("{id}/toggle")]
        public async Task<IActionResult> ToggleLlmModel(int id)
        {
            try
            {
                var tenantId = await ResolveTenantIdAsync();
                if (!tenantId.HasValue)
                {
                    return Forbid();
                }

                var model = await _context.LlmModels
                    .FirstOrDefaultAsync(m => m.Id == id);

                if (model == null)
                {
                    return NotFound(new { message = "LLM模型不存在" });
                }

                model.IsEnabled = !model.IsEnabled;
                model.UpdatedAt = DateTime.UtcNow;

                await _context.SaveChangesAsync();

                return NoContent();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error toggling LLM model {Id}", id);
                return StatusCode(500, new { message = "切换LLM模型状态失败" });
            }
        }
    }
}

